package com.bugsnag.ohos;


import com.bugsnag.ohos.ndk.NativeBridge;
import com.bugsnag.ohos.util.OhosLog;

import java.util.concurrent.atomic.AtomicBoolean;

public class NdkPlugin implements Plugin {

    private static final String LOAD_ERR_MSG = "Native library could not be linked. Bugsnag will ";

    private final LibraryLoader libraryLoader = new LibraryLoader();
    private final AtomicBoolean oneTimeSetupPerformed = new AtomicBoolean(false);

    public  native void enableCrashReporting();

    public  native void disableCrashReporting();

    public  native String getBinaryArch();

    private NativeBridge nativeBridge = null;
    private Client client;

    private NativeBridge initNativeBridge(Client client) {
        NativeBridge nativeBridge = new NativeBridge();
        client.addObserver(nativeBridge);
        client.setupNdkPlugin();
        return nativeBridge;
    }

    @Override
    public void load(Client client) {
        this.client = client;
        if (!oneTimeSetupPerformed.getAndSet(true)) {
            performOneTimeSetup(client);
        }
        if (libraryLoader.isLoaded()) {
            OhosLog.d("bugsdemo","NdkPlugin load.... c++ enableCrashReporting");
            enableCrashReporting();
            client.logger.i("Initialised NDK Plugin");
        }
    }

    @Override
    public void unload() {
        if (libraryLoader.isLoaded()) {
            disableCrashReporting();
            if (nativeBridge != null && client != null) {
                client.removeObserver(nativeBridge);
            }
        }
    }

    private void performOneTimeSetup(Client client) {
        OhosLog.d("NdkPlugin","performOneTimeSetup()");
        libraryLoader.loadLibrary("bugsnag-ndk", client, new OnErrorCallback() {
            @Override
            public boolean onError(Event event) {
                Error error = event.getErrors().get(0);
                error.setErrorClass("NdkLinkError");
                error.setErrorMessage(LOAD_ERR_MSG);
                return true;
            }
        });
        if (libraryLoader.isLoaded()) {
            OhosLog.d("NdkPlugin","initNativeBridge()");
            client.setBinaryArch(getBinaryArch());
            nativeBridge = initNativeBridge(client);
        } else {
            client.logger.e(LOAD_ERR_MSG);
        }
    }


    public Long getUnwindStackFunction() {
        OhosLog.d("NdkPlugin","getUnwindStackFunction()");
        NativeBridge bridge = nativeBridge;
        if (bridge != null) {
            return bridge.getUnwindStackFunction();
        }
        OhosLog.d("NdkPlugin","getUnwindStackFunction()");
        return 0L;
    }
}
